package com.faxsun.admin.dao.provide.metadata;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.broadleafcommerce.common.BroadleafEnumerationType;
import org.broadleafcommerce.openadmin.dto.BasicFieldMetadata;
import org.broadleafcommerce.openadmin.server.dao.DynamicEntityDao;
import org.broadleafcommerce.openadmin.server.dao.provider.metadata.BasicFieldMetadataProvider;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.faxsun.core.catalog.domain.CountryEnum;

@Component
@Scope("prototype")
public class FSBasicFieldMetadataProvider extends BasicFieldMetadataProvider {

	@SuppressWarnings("rawtypes")
	protected void setupBroadleafEnumeration(String broadleafEnumerationClass,
			BasicFieldMetadata fieldMetadata, DynamicEntityDao dynamicEntityDao) {
		try {

			Map<String, String> enumVals;
			Class<?> broadleafEnumeration = Class
					.forName(broadleafEnumerationClass);

			Method typeMethod = broadleafEnumeration.getMethod("getType");
			Method friendlyTypeMethod = broadleafEnumeration
					.getMethod("getFriendlyType");
			Field types = dynamicEntityDao.getFieldManager().getField(
					broadleafEnumeration, "TYPES");

			if (Comparable.class.isAssignableFrom(broadleafEnumeration)) {
				enumVals = new LinkedHashMap<String, String>();
				Set<BroadleafEnumerationType> blcEnumSet = new TreeSet<BroadleafEnumerationType>();
				if (types != null) {
					Map typesMap = (Map) types.get(null);
					@SuppressWarnings("unchecked")
					Collection<CountryEnum> values = typesMap.values();
					List<CountryEnum> lists=new ArrayList<CountryEnum>(values);
					Collections.sort(lists);
					for (Object value : lists) {
						blcEnumSet.add((BroadleafEnumerationType) value);
					}

					for (Object value : lists) {
						enumVals.put((String) friendlyTypeMethod.invoke(value),
								(String) typeMethod.invoke(value));
					}
				}
			} else {
				enumVals = new TreeMap<String, String>();
				if (types != null) {
					Map typesMap = (Map) types.get(null);
					for (Object value : typesMap.values()) {
						enumVals.put((String) friendlyTypeMethod.invoke(value),
								(String) typeMethod.invoke(value));
					}
				} else {
					Field[] fields = dynamicEntityDao
							.getAllFields(broadleafEnumeration);
					for (Field field : fields) {
						boolean isStatic = Modifier.isStatic(field
								.getModifiers());
						if (isStatic
								&& field.getType().isAssignableFrom(
										broadleafEnumeration)) {
							enumVals.put((String) friendlyTypeMethod
									.invoke(field.get(null)),
									(String) typeMethod.invoke(field.get(null)));
						}
					}
				}
			}

			String[][] enumerationValues = new String[enumVals.size()][2];
			int j = 0;
			for (String key : enumVals.keySet()) {
				enumerationValues[j][0] = enumVals.get(key);
				enumerationValues[j][1] = key;
				j++;
			}
			fieldMetadata.setEnumerationValues(enumerationValues);
			fieldMetadata.setEnumerationClass(broadleafEnumerationClass);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
